package org.example.paymentservice.service.impl;

import lombok.RequiredArgsConstructor;
import org.example.paymentservice.dto.PaymentRequest;
import org.example.paymentservice.dto.RefundRequest;
import org.example.paymentservice.entity.Order;
import org.example.paymentservice.entity.PaymentTransaction;
import org.example.paymentservice.repository.OrderRepository;
import org.example.paymentservice.repository.PaymentTransactionRepository;
import org.example.paymentservice.service.PaymentService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityNotFoundException;

@Service
@RequiredArgsConstructor
public class PaymentServiceImpl implements PaymentService {
    private final OrderRepository orderRepository;
    private final PaymentTransactionRepository transactionRepository;
    private final PaymentProviderClient paymentProviderClient;

    @Override
    @Transactional
    public PaymentTransaction processPayment(PaymentRequest paymentRequest) {
        Order order = orderRepository.findById(paymentRequest.getOrderId())
                .orElseThrow(() -> new EntityNotFoundException("Order not found"));

        // 创建支付交易记录
        PaymentTransaction transaction = new PaymentTransaction();
        transaction.setOrder(order);
        transaction.setAmount(order.getAmount());
        transaction.setType(PaymentTransaction.TransactionType.PAYMENT);
        transaction.setPaymentProvider(paymentRequest.getPaymentMethod().toString());

        try {
            // 调用支付提供商API
            String transactionId = paymentProviderClient.processPayment(
                    paymentRequest.getPaymentMethod(),
                    order.getAmount(),
                    paymentRequest.getPaymentDetails()
            );

            transaction.setProviderTransactionId(transactionId);
            transaction.setStatus(PaymentTransaction.TransactionStatus.SUCCESS);
            
            // 更新订单状态
            order.setStatus(Order.PaymentStatus.PAID);
            order.setTransactionId(transactionId);
            orderRepository.save(order);
        } catch (Exception e) {
            transaction.setStatus(PaymentTransaction.TransactionStatus.FAILED);
            transaction.setErrorMessage(e.getMessage());
            order.setStatus(Order.PaymentStatus.FAILED);
            orderRepository.save(order);
        }

        return transactionRepository.save(transaction);
    }

    @Override
    @Transactional
    public PaymentTransaction processRefund(RefundRequest refundRequest) {
        Order order = orderRepository.findById(refundRequest.getOrderId())
                .orElseThrow(() -> new EntityNotFoundException("Order not found"));

        if (order.getStatus() != Order.PaymentStatus.PAID) {
            throw new IllegalStateException("Order is not in PAID status");
        }

        PaymentTransaction transaction = new PaymentTransaction();
        transaction.setOrder(order);
        transaction.setAmount(refundRequest.getAmount());
        transaction.setType(PaymentTransaction.TransactionType.REFUND);
        transaction.setPaymentProvider(order.getPaymentMethod().toString());

        try {
            String refundId = paymentProviderClient.processRefund(
                    order.getTransactionId(),
                    refundRequest.getAmount(),
                    refundRequest.getReason()
            );

            transaction.setProviderTransactionId(refundId);
            transaction.setStatus(PaymentTransaction.TransactionStatus.SUCCESS);
            
            order.setStatus(Order.PaymentStatus.REFUNDED);
            orderRepository.save(order);
        } catch (Exception e) {
            transaction.setStatus(PaymentTransaction.TransactionStatus.FAILED);
            transaction.setErrorMessage(e.getMessage());
        }

        return transactionRepository.save(transaction);
    }

    @Override
    public Order getOrderById(Long orderId) {
        return orderRepository.findById(orderId)
                .orElseThrow(() -> new EntityNotFoundException("Order not found"));
    }

    @Override
    @Transactional
    public void validatePayment(String paymentId) {
        PaymentTransaction transaction = transactionRepository.findByProviderTransactionId(paymentId)
                .orElseThrow(() -> new EntityNotFoundException("Transaction not found"));

        if (transaction.getStatus() == PaymentTransaction.TransactionStatus.PENDING) {
            boolean isValid = paymentProviderClient.validatePayment(paymentId);
            if (isValid) {
                transaction.setStatus(PaymentTransaction.TransactionStatus.SUCCESS);
                transaction.getOrder().setStatus(Order.PaymentStatus.PAID);
            } else {
                transaction.setStatus(PaymentTransaction.TransactionStatus.FAILED);
                transaction.getOrder().setStatus(Order.PaymentStatus.FAILED);
            }
            transactionRepository.save(transaction);
            orderRepository.save(transaction.getOrder());
        }
    }
}